package main

import (
	"fmt"
	"runtime"
	"sync"
	"time"
)

func main(){
	runtime.GOMAXPROCS(runtime.NumCPU())
	//ch := make(chan int)
	//go func() {
	//	ch<- 42
	//}()
	//<-ch

	//for i := 0; i < 24; i++ {
	//	c := timer(1*time.Second)
	//	<-c
	//}

	//var Ball int
	//table := make(chan int)
	//go player(table)
	//go player(table)
	//go player(table)
	//table <- Ball
	//time.Sleep(1 * time.Second)
	//<-table

	//ch := make(chan int)
	//out := make(chan int)
	//go producer(ch, 200 * time.Millisecond)
	//go producer(ch, 250 * time.Millisecond)
	//go reader(out)
	//for i := range ch {
	//	out<-i
	//}

	var wg sync.WaitGroup
	wg.Add(36)
	go pool(&wg, 36, 50)
	wg.Wait()
}

func worker(tasksCh <-chan int, wg *sync.WaitGroup){
	defer wg.Done()
	for{
		task, ok := <-tasksCh
		if !ok{
			return
		}
		d := time.Duration(task) * time.Millisecond
		time.Sleep(d)
		fmt.Println("processing task", task)
	}
}

func pool(wg *sync.WaitGroup, workers, tasks int){
	tasksCh := make(chan int)
	for i := 0; i <workers ; i++ {
		go worker(tasksCh, wg)
	}
	for i := 0; i < tasks; i++ {
		tasksCh<-i
	}
	close(tasksCh)
}

func producer(ch chan int, d time.Duration){
	var i int
	for{
		ch<-i
		i++
		time.Sleep(d)
	}
}

func reader(out chan int){
	for x:= range out{
		fmt.Println(x)
	}
}

func player(table chan int){
	for{
		ball := <-table
		ball++
		time.Sleep(100 * time.Millisecond)
		table<-ball
	}
}


func timer(d time.Duration)<-chan int{
	c := make(chan int)
	go func() {
		time.Sleep(d)
		c<-1
	}()
	return c
}